﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Utilities;

namespace BusinessLogicLayer
{
    public class NghiPhepManager
    {
        /// <summary>
        /// Chuyển 1 hàng trong datattable thành NghiPhep
        /// </summary>
        /// <param name="row">Hang</param>
        /// <returns>Kết quả</returns>
        ActionResultAsList<NghiPhep> Parser(DataRow row)
        {
            ActionResultAsList<NghiPhep> rs = new ActionResultAsList<NghiPhep>();
            NghiPhep np = new NghiPhep();
            
            // Mã nhân viên
            string manv = row[0].ToString().Trim();
            if (String.IsNullOrEmpty(manv))
                rs.AddException(new Exception("Không đúng định dạng mã nhân viên. "));
            else
                np.MaNhanVien = manv;
            
            // Kiem tra ngay bat đầu
            try
            {
                np.NgayNghi = Convert.ToDateTime(row[1]);
            }
            catch (Exception)
            {
                rs.AddException(new Exception("Không đúng định dạng ngày nghỉ. "));
            }

            // Kiểm tra ngày đi làm
            try
            {
                np.NgayDiLam = Convert.ToDateTime(row[2]);
            }
            catch (Exception)
            {
                rs.AddException(new Exception("Không đúng định dạng ngày đi làm. "));
            }

            try
            {
                if (np.NgayDiLam <= np.NgayNghi)
                    rs.AddException(new Exception("Ngày đi làm bé hơn ngày nghỉ."));
            }
            catch (Exception)
            {
            }

            // Lý do
            np.LyDo = row[3].ToString().Trim();

            
            rs.ObjectList.Add(np);
            return rs;
        }

        bool CheckDateValidated(NghiPhep entity)
        {
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                ctx.Configuration.LazyLoadingEnabled = false;
                NghiPhep np = ctx.NghiPheps.Where
                    (n => n.MaNhanVien == entity.MaNhanVien && n.NgayNghi <= entity.NgayNghi && entity.NgayNghi < n.NgayDiLam)
                    .FirstOrDefault<NghiPhep>();
                if (np != null)
                    return false;
                np = ctx.NghiPheps.Where
                    (n => n.MaNhanVien == entity.MaNhanVien && n.NgayNghi <= entity.NgayDiLam && entity.NgayDiLam < n.NgayDiLam)
                    .FirstOrDefault<NghiPhep>();
                if (np != null)
                    return false ;
                np = ctx.NghiPheps.Where
                    (n => n.MaNhanVien == entity.MaNhanVien && entity.NgayNghi <= n.NgayNghi && n.NgayDiLam <= entity.NgayDiLam)
                    .FirstOrDefault<NghiPhep>();
                if (np != null)
                    return false;
            }
            return true;
        }

        public ActionResultAsList<NghiPhep> ThemNghiPhep(DataTable Table)
        {
            ActionResultAsList<NghiPhep> rs = new ActionResultAsList<NghiPhep>();
            int dem = 0;
            foreach (DataRow r in Table.Rows)
            {
                ActionResultAsList<NghiPhep> re = Parser(r);
                string error = "Dòng " + dem +":\n";
                if (!re.Success)
                {
                    error += re.ToString();
                }
                else
                {
                    if (CheckDateValidated(re.ObjectList[0]))
                    {
                        ActionResult ss = ThemNghiPhep(re.ObjectList[0]);
                        if (ss.Success)
                        {

                            rs.ObjectList.Add(re.ObjectList[0]);
                        }
                        else
                        {
                            error += ss.ToString();
                        }
                    }
                    else
                        error += "Nhân viên: " + re.ObjectList[0].MaNhanVien + " đã có thông tin nghỉ phép trong khoảng thời gian này. ";
                }
                if (error != "Dòng " + dem++ + ":\n")
                    rs.AddException(new Exception(error));
            }
            return rs;
        }

        public ActionResult ThemNghiPhep(NghiPhep entity)
        {
            ActionResult rs = new ActionResult();
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    ctx.Configuration.LazyLoadingEnabled = false;
                    NhanVien nv = ctx.NhanViens.Where(n => n.MaNhanVien == entity.MaNhanVien).FirstOrDefault<NhanVien>();
                    if (nv != null)
                    {
                        ctx.NghiPheps.Add(entity);
                        ctx.SaveChanges();
                        ctx.Entry(entity).Reference(e => e.NhanVien).Load();
                    }
                    else
                        rs.AddException(new Exception("Không tồn tại mã nhân viên: " + entity.MaNhanVien + ". "));
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    rs.AddException(ex);
                }
            }
            return rs;
        }

        public ActionResult CapNhatNghiPhep(ref NghiPhep entity)
        {
            ActionResult rs = new ActionResult();
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    int ma = entity.MaNghiPhep;
                    NghiPhep np = ctx.NghiPheps.Include("NhanVien").Where(n => n.MaNghiPhep == ma).FirstOrDefault();
                    if (np != null)
                    {
                        np.LyDo = entity.LyDo;
                        np.MaNhanVien = entity.MaNhanVien;
                        np.NgayDiLam = entity.NgayDiLam;
                        np.NgayNghi = entity.NgayNghi;
                        ctx.Entry(np).State = System.Data.Entity.EntityState.Modified;
                        ctx.SaveChanges();
                        entity = np;
                    }
                    else
                        rs.AddException(new Exception("Không tồn tại mã nghỉ phép: " + entity.MaNghiPhep + "."));
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    rs.AddException(ex);
                }
            }
            return rs;
        }

        public ActionResult XoaNghiPhep(int MaNghiPhep)
        {
            ActionResult rs = new ActionResult();
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    NghiPhep np = ctx.NghiPheps.Where(a => a.MaNghiPhep == MaNghiPhep).FirstOrDefault<NghiPhep>();
                    if (np != null)
                    {
                        ctx.Entry(np).State = System.Data.Entity.EntityState.Deleted;
                        ctx.SaveChanges();
                    }
                    else
                        rs.AddException(new Exception("Không tồn tại mã nghỉ phép: " + MaNghiPhep + "."));
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    rs.AddException(ex);
                }

            }
            return rs;
        }

        public ActionResultAsList<NghiPhep> LayDanhSachNghiPhep()
        {
            ActionResultAsList<NghiPhep> rs = new ActionResultAsList<NghiPhep>();
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    rs.ObjectList = ctx.NghiPheps.Include("NhanVien").ToList();
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    rs.AddException(ex);
                }
            }
            return rs;
        }

        public ActionResultAsList<NghiPhep> LayDanhSachNghiPhepHienHanh()
        {
            return TimTheoNgay(DateTime.Today);
        }

        public ActionResultAsList<NhanVien> LayDanhsachNhanVien()
        {
            ActionResultAsList<NhanVien> rs = new ActionResultAsList<NhanVien>();
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    rs.ObjectList = ctx.NhanViens.Where(nv => nv.TrangThai != TrangThaiNV.NghiViec && nv.TrangThai != TrangThaiNV.OnSite &&
                        ctx.NghiPheps.Where(np => np.NgayDiLam > DateTime.Today && np.NgayNghi <= DateTime.Today && np.MaNhanVien == nv.MaNhanVien).FirstOrDefault<NghiPhep>() == null).ToList();
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    rs.AddException(ex);
                }
            }
            return rs;
        }

        public NghiPhep LayNghiPhep(int MaNP)
        {
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    return ctx.NghiPheps.Include("NhanVien").Include("NhanVien.ChucVu1").Where(np => np.MaNghiPhep == MaNP).FirstOrDefault();
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    return null;
                }
            }
        }

        public ActionResultAsList<NghiPhep> TimTheoNgay(DateTime date)
        {
            ActionResultAsList<NghiPhep> rs = new ActionResultAsList<NghiPhep>();
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    rs.ObjectList = ctx.NghiPheps.Include("NhanVien").Where(np => np.NgayDiLam > date && np.NgayNghi <= date).ToList();
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    rs.AddException(ex);
                }
            }
            return rs;
        }

        public ActionResultAsList<NghiPhep> TimTheoNhanVien(string MaNV)
        {
            ActionResultAsList<NghiPhep> rs = new ActionResultAsList<NghiPhep>();
            using (QLNVDbContext ctx = new QLNVDbContext())
            {
                try
                {
                    rs.ObjectList = ctx.NghiPheps.Include("NhanVien").Where(np => np.MaNhanVien == MaNV).ToList();
                }
                catch (Exception ex)
                {
                    Logger.Write(ex.Message);
                    rs.AddException(ex);
                }
            }
            return rs;
        }

    }
}
